<template>
  <div class="page-list-live">
    <PageList>
      <template #header>{{ title }}</template>
      <!-- 表单搜索 -->
      <template #filter>
        <ListFilter
          :form="topFilter"
          @search="handleSearch"
          @changItemHandler="changHandler"
          @reset="handleResetOne"
        ></ListFilter>
      </template>
      <!-- 按钮 -->
      <template #tips>
        <el-button icon="el-icon-delete" type="danger" @click="batchDeletion">批量删除</el-button>
        <el-button icon="el-icon-folder-remove" type="primary" @click="exportHandler">导出</el-button>
        <el-button icon="el-icon-document-add" type="primary" @click="handleAdd">补录</el-button>
      </template>
      <!-- 表格 -->
      <template #table>
        <ListTable
          ref="RefListTable"
          :loading="tableLoading"
          :table-data="tableData"
          :table-col="tableCol"
          :enter-time-start="EnterTimeStart"
          :enter-time-end="EnterTimeEnd"
          @selectChange="handleSelectionChange"
        >
          <template slot="col1" slot-scope="scope" style="min-width: 200px">
            <el-button
              :disabled="scope.row.isManually"
              icon="el-icon-s-release"
              :loading="scope.row.loadingSee"
              size="mini"
              type="text"
              style="margin-left: 0px; margin-right: 10px; padding: 0"
              @click="handleRowDetails(scope.row)"
            >{{ scope.row.isManually ? '补录' : '详情' }}</el-button>
            <el-button
              icon="el-icon-edit"
              :loading="scope.row.loadingEdit"
              size="mini"
              style="margin-left: 0px; margin-right: 10px; padding: 0"
              type="text"
              @click="handleRowEdit(scope.row)"
            >编辑</el-button>
            <el-button
              :loading="scope.row.loadingDel"
              size="mini"
              icon="el-icon-delete"
              style="color: red; margin-left: 0px; margin-right: 10px; padding: 0"
              type="text"
              @click="handleRowDel(scope.row)"
            >删除</el-button>
          </template>
        </ListTable>
      </template>
    </PageList>
    <addAttendance ref="addAttendance" @success="afterEditSuccess"></addAttendance>
    <detailsAttendance ref="detailsAttendance" @success="afterEditSuccess"></detailsAttendance>
    <editAttendanceStatistics ref="editAttendanceStatistics" @success="afterEditSuccess"></editAttendanceStatistics>
  </div>
</template>
<script>
import listMixin from '@/mixins/list'
import addAttendance from './components/addEditAttendance'
import editAttendanceStatistics from './components/editAttendanceStatistics.vue'
import detailsAttendance from './components/detailsAttendance.vue'
import ListFilter from '@/components/ListFilter'
import { department, job, work, attendanceList } from '@/api/api'
import { getToken } from '@/utils/auth'
import { localhostUrl } from '@/utils/setUrl.js'
import { parseTime } from '@/utils'
export default {
  components: {
    ListFilter,
    addAttendance,
    editAttendanceStatistics,
    detailsAttendance
  },
  mixins: [listMixin],
  data() {
    return {
      title: '考勤统计',
      EnterTimeStart: (function () {
        var d = new Date()
        return d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + '01' + ' 00:00:00'
      })(),
      EnterTimeEnd: (function () {
        // 现在的时间
        var date = new Date()
        // 获取当前月份
        var currentMonth = date.getMonth()
        // 获取下一个月
        var nextMonth = ++currentMonth
        // 获取下个月的1号
        var nextMonthFirstDay = new Date(date.getFullYear(), nextMonth, 1)
        // 设置一天的时间
        var oneDay = 1000 * 60 * 60 * 24
        // 上个月的第一天减去一天得到当前月的最后一天的时间
        var lastTime = new Date(nextMonthFirstDay - oneDay)
        // 得到当前月
        var month = parseInt(lastTime.getMonth() + 1)
        // 得到当前月最后一天
        var day = lastTime.getDate()
        if (month < 10) {
          month = '0' + month
        }
        if (day < 10) {
          day = '0' + day
        }

        return date.getFullYear() + '-' + month + '-' + day + ' 00:00:00'
      })(),
      startTime: null,
      endTime: null,
      deleteList: {
        id: ''
      },
      pageIndex: 1,
      topFilter: {
        DepartmentName: { label: '部门', placeholder: '请选择部门', type: 'select', arr: this.dptList },
        JobName: { label: '职位', placeholder: '请选择职位', type: 'select', arr: this.jobList },
        WorkType: { label: '工种', placeholder: '请选择工种', type: 'select', arr: this.workList },
        Name: { label: '员工名称', placeholder: '请输入员工名称' },
        RFID: { label: 'RFID卡', placeholder: '请输入RFID卡' },
        AccessCardID: { label: '门禁ID', placeholder: '请输入门禁ID' },
        enterTime: { label: '考勤日期', type: 'dateonly', arr: ['attendanceDate', 'attendanceDate'] }
      },
      // keyList:["code","name"],
      // 部门数据
      dptList: [],
      // 职位数据
      jobList: [],
      // 工种数据
      workList: [],
      tableData: [],
      tableCol: [
        { type: 'selection' },
        { type: 'index', label: '序号', width: '60px' },
        { prop: 'code', label: '员工编号' },
        { prop: 'name', label: '员工名称' },
        { prop: 'rfid', label: 'RFID卡号' },
        { prop: 'accessCardID', label: '门禁卡号', minWidth: '120px' },
        { prop: 'departmentName', label: '部门', minWidth: '160px' },
        { prop: 'jobName', label: '职位' },
        { prop: 'workType', label: '工种' },
        {
          prop: 'attendanceDate',
          label: '考勤日期',
          width: '160px',
          formatter(row, col, cell) {
            return parseTime(new Date(row.attendanceDate).getTime(), '{y}-{m}-{d}')
          }
        },
        // { prop: 'entertime', label: '进场时间', width: '160px' },
        // { prop: 'leaveTime', label: '出场时间', width: '160px' },
        { prop: 'enterCount', label: '进场次数' },
        // { prop: 'attendanceType', label: '考勤方式', minWidth: '120px' },
        { prop: 'totalWorkHours', label: '累计工时', minWidth: '110px' },
        { label: '操作', custom: 'col1', minWidth: '200px' }
      ]
    }
  },
  mounted() {
    this.startTime = this.EnterTimeStart
    this.endTime = this.EnterTimeEnd
    // 获取下拉框数据并赋值给查询组件
    this.threeList()
    this.$store.dispatch('user/setAttendanceDate', {
      EnterTimeStart: this.EnterTimeStart,
      EnterTimeEnd: this.EnterTimeEnd,
      status: true
    })
  },
  beforeDestroy() {
    this.$store.dispatch('user/setAttendanceDate', { EnterTimeStart: null, EnterTimeEnd: null, status: false })
  },
  methods: {
    // 下拉框改变
    changHandler(value) {
      if (value.key === 'attendanceDate') {
        this.EnterTimeStart = value.val[0]
        this.EnterTimeEnd = value.val[1]
      }
    },
    // 重置
    async handleResetOne(value) {
      console.log(value.EnterTimeStart)
      this.EnterTimeStart = value.EnterTimeStart
      this.EnterTimeEnd = value.EnterTimeEnd
      delete value.search
      await this.handleReset(value)
      this.$store.dispatch('user/setAttendanceDate', {
        EnterTimeStart: this.EnterTimeStart,
        EnterTimeEnd: this.EnterTimeEnd,
        status: true
      })
    },
    // 导出
    async exportHandler() {
      try {
        let that = this
        let url = localhostUrl + `/Attendance/ExcelFile`
        let xhr = new XMLHttpRequest()
        xhr.open('post', url, true)
        xhr.setRequestHeader('Content-Type', 'application/json')
        xhr.setRequestHeader('Authorization', `Bearer ${getToken()}`)
        xhr.responseType = 'blob' // 返回类型blob  blob 存储着大量的二进制数据
        xhr.onload = function () {
          if (this.status === 200) {
            let blob = this.response
            let reader = new FileReader()
            reader.readAsDataURL(blob) // 转换为base64，可以直接放入a标签href
            reader.onload = function (e) {
              var a = document.createElement('a') // 转换完成，创建一个a标签用于下载
              a.download = parseTime(new Date(), '{y}-{m}-{d}') + ' 考勤统计.xls'
              a.href = e.target.result
              document.body.appendChild(a) // 修复firefox中无法触发click
              a.click()
              document.body.removeChild(a)
            }
            alert('导出成功，请保存！')
          }
        }
        let str = JSON.stringify(this.serchObj)
        xhr.send(str) // 发送ajax请求
      } catch (err) {
        this.$message.error('导出失败！')
      }
    },
    // 批量删除
    batchDeletion() {
      if (!this.deleteList.id) {
        this.$message.warning('请选择要删除的数据！')
        return
      }
      this.$_delConfirm('所选数据', () => {
        this.delRowReq(this.deleteList)
      })
    },
    // 选中事件
    handleSelectionChange(event) {
      if (event.length > 0) {
        let ary = []
        event.forEach(item => {
          ary.push(item.id)
        })
        if (ary.length > 1) {
          this.deleteList.id = ary.join(',')
        } else {
          this.deleteList.id = ary[0]
        }
      } else {
        this.deleteList.id = ''
      }
    },
    // 部门
    async dptHandler() {
      try {
        let obj = { pageIndex: 1, pageSize: 1e8 }
        let res = await department('post', obj, false)
        if (res.code === 200) {
          // this.dptList = [{
          //   label: '空',
          //   value: '空'
          // }]
          this.dptList = []
          res.data.items.map(item => {
            this.dptList.push({
              label: item.deptName,
              value: item.deptName
            })
          })
        }
      } catch (err) {
        let er = err
        // this.$message.error('部门查询失败！')
      }
    },
    // 职位
    async jobHandler() {
      try {
        let obj = { pageIndex: 1, pageSize: 1e8 }
        let res = await job('post', obj, false)
        if (res.code === 200) {
          // this.jobList = [{
          //   label: '空',
          //   value: '空'
          // }]
          this.jobList = []
          res.data.items.map(item => {
            this.jobList.push({
              label: item.jobTitle,
              value: item.jobTitle,
              department: item.department
            })
          })
        }
      } catch (err) {
        let er = err
        // this.$message.error('区域查询失败！')
      }
    },
    // 工种
    async workHandler() {
      try {
        let obj = { pageIndex: 1, pageSize: 1e8 }
        let res = await work('post', obj, false)
        if (res.code === 200) {
          // this.workList = [{
          //   label: '空',
          //   value: '空'
          // }]
          this.workList = []
          res.data.items.map(item => {
            this.workList.push({
              label: item.workName,
              value: item.workName
            })
          })
        }
      } catch (err) {
        let er = err
        // this.$message.error('工种查询失败！')
      }
    },
    // 查询部门，职位，工种
    async threeList() {
      await this.jobHandler()
      await this.dptHandler()
      await this.workHandler()
      this.$nextTick(() => {
        this.topFilter = {
          DepartmentName: { label: '部门', placeholder: '请选择部门', type: 'select', arr: this.dptList },
          JobName: { label: '职位', placeholder: '请选择职位', type: 'select', arr: this.jobList },
          WorkType: { label: '工种', placeholder: '请选择工种', type: 'select', arr: this.workList },
          Name: { label: '员工名称', placeholder: '请输入员工名称' },
          RFID: { label: 'RFID卡', placeholder: '请输入RFID卡' },
          AccessCardID: { label: '门禁ID', placeholder: '请输入门禁ID' },
          attendanceDate: { label: '考勤日期', type: 'dateonly', arr: ['attendanceDate', 'attendanceDate'] }
        }
      })
    },
    // 请求列表数据
    async getList(query) {
      if (!query) { return }
      this.tableLoading = true
      try {
        let obj = query || { pageIndex: 1, pageSize: 10, search: [] }

        obj.orderBy = 'createdTime'
        obj.orderByAscent = false
        if (!obj.search) {
          obj.search = []
        }
        obj.search.map(r => {
          if (r.key == 'attendanceDate' && r.operation == 4) {
            r.value = this.EnterTimeStart
          }
          if (r.key == 'attendanceDate' && r.operation == 5) {
            r.value = this.EnterTimeEnd
          }
        })
        if (!obj.search.find(r => r.key == 'attendanceDate')) {
          obj.search.push({
            key: 'attendanceDate',
            value: this.EnterTimeStart,
            operation: 4
          })
          obj.search.push({
            key: 'attendanceDate',
            value: this.EnterTimeEnd,
            operation: 5
          })
        }

        // 如果选择空数据，需设置值为null
        obj.search.forEach((edit, index) => {
          if (edit.key === 'DepartmentName' && edit.value === '空') {
            edit.value = null
          } else if (edit.key === 'JobName' && edit.value === '空') {
            edit.value = null
          } else if (edit.key === 'WorkType' && edit.value === '空') {
            edit.value = null
          }
        })
        if (!this.EnterTimeStart) {
          this.tableLoading = false
          return
        }

        const {
          data: { items: resData, count: total, pageIndex }
        } = await attendanceList('post', obj, false)
        this.tableData = []
        this.$nextTick(() => {
          this.tableData = resData.map(item => {
            item.loadingEdit = false
            item.loadingSee = false
            return item
          })
          this.$refs['RefListTable'].update({ page: Number(pageIndex), count: total })
          this.tableLoading = false
        })
      } catch (err) {
        this.tableLoading = false
        this.tableData = []
      }
    },
    async afterEditSuccess() {
      this.getList(this.serchObj)
    },
    // 新增
    handleAdd() {
      let objData = {
        // 进入哪一个程序
        status: 'add',
        apiKey: {
          add: '/Attendance' // 添加
        }
      }
      this.$refs['addAttendance'].openOne(objData)
      this.$refs['addAttendance'].getDepartmentList()
    },
    // 编辑
    async handleRowEdit(row) {
      row.loadingEdit = true
      await this.$refs['editAttendanceStatistics'].getDepartmentList()

      let objData = {
        // 源数据
        row: row,
        // 源id
        id: row.id,
        // 查询参数
        apiKey: {
          search: '/Attendance/Search/',
          add: '/Attendance',
          put: '/Attendance/' + row.id
        }
      }
      this.$refs['editAttendanceStatistics'].openTwo(objData)
      row.loadingEdit = false
    },
    // 详情
    handleRowDetails(row) {
      row.loadingSee = true
      let ary = []
      var attendanceDateFrom = parseTime(new Date(row.attendanceDate).getTime(), '{y}-{m}-{d}')
      var attendanceDateTo = parseTime(new Date(row.attendanceDate).getTime(), '{y}-{m}-{d} 23:59:59')
      if (row.leaveTime && row.entertime) {
        ary = [
          {
            key: 'employeeId',
            value: row.employeeId,
            operation: 0,
            sequence: 0,
            relationship: 0
          },
          {
            key: 'leaveTime',
            value: attendanceDateFrom,
            operation: 4,
            sequence: 1,
            relationship: 0
          },
          {
            key: 'leaveTime',
            value: attendanceDateTo,
            operation: 5,
            sequence: 2,
            relationship: 0
          }
        ]
      } else if (!row.leaveTime && row.entertime) {
        ary = [
          {
            key: 'employeeId',
            value: row.employeeId,
            operation: 0,
            sequence: 0,
            relationship: 0
          },
          {
            key: 'enterTime',
            value: attendanceDateFrom,
            operation: 4,
            sequence: 1,
            relationship: 0
          }
        ]
      } else {
        this.$message.error('无进场时间无法查询！')
        return
      }
      let objData = {
        // 进入哪一个程序
        status: 'details',
        // 源数据
        row: row,
        // 源id
        id: row.id,
        // 查询参数
        searchData: {
          url: '/Path/Search',
          method: 'post',
          data: ary
        },
        apiKey: {
          search: '/Path/Search',
          add: '/Path',
          put: '/Path/'
        }
      }
      this.$refs['detailsAttendance'].openOne(objData)
      row.loadingSee = false
    },
    async delRowReq(row) {
      try {
        const obj = { id: row.id, value: null }
        await attendanceList('delete', obj, true)
        row.loadingDel = false
        this.getList(this.serchObj)
        this.$message({
          type: 'success',
          message: '删除成功'
        })
      } catch (err) {
        row.loadingDel = false
        this.$message({
          type: 'error',
          message: '删除失败'
        })
      }
    },
    handleRowDel(row) {
      row.loadingDel = true
      this.$_delConfirm(
        '考勤记录',
        () => {
          this.delRowReq(row)
        },
        () => {
          row.loadingDel = false
        }
      )
    }
  }
}
</script>

<style lang="scss" scoped></style>
